#include"../include/ICG.h"

// 四元式结构体
typedef struct {
    char op[8];       // 操作符
    char arg1[32];    // 操作数1
    char arg2[32];    // 操作数2
    char result[32];  // 结果
} Quadruple;

// 表达式节点
typedef struct ExprNode {
    char value[32];   // 值（变量名或临时变量）
    struct ExprNode *left;
    struct ExprNode *right;
} ExprNode;

// 语法树节点类型
typedef enum {
    NODE_IDENTIFIER,
    NODE_NUMBER,
    NODE_OPERATOR,
    NODE_ASSIGNMENT
} NodeType;

// 语法树节点
typedef struct ASTNode {
    NodeType type;
    char value[32];
    struct ASTNode *left;
    struct ASTNode *right;
} ASTNode;

// 全局变量
Quadruple quads[100]; // 四元式数组
int quad_count = 0;   // 四元式计数器
int temp_count = 0;   // 临时变量计数器
char input[256];      // 输入表达式
int pos = 0;          // 当前解析位置
char token[32];       // 当前token
char token_type;      // token类型：'i'标识符，'n'数字，'o'操作符，'('，')'，'='，'\0'结束

// 函数声明
void next_token();
ASTNode* parse_expression();
ASTNode* parse_term();
ASTNode* parse_factor();
ASTNode* parse_assignment();
char* generate_code(ASTNode* node);
char* new_temp();
void gen_quad(const char* op, const char* arg1, const char* arg2, const char* result);
void print_quads();
void print_ast(ASTNode* node, int depth);

// 获取下一个token
void next_token() {
    // 跳过空白字符
    while (input[pos] == ' ' || input[pos] == '\t') pos++;
    
    // 检查是否到达字符串末尾
    if (input[pos] == '\0') {
        token[0] = '\0';
        token_type = '\0';
        return;
    }
    
    // 处理标识符（以字母开头）
    if (isalpha(input[pos])) {
        int i = 0;
        while (isalnum(input[pos]) || input[pos] == '_') {
            token[i++] = input[pos++];
        }
        token[i] = '\0';
        token_type = 'i';
        return;
    }
    
    // 处理数字
    if (isdigit(input[pos])) {
        int i = 0;
        while (isdigit(input[pos])) {
            token[i++] = input[pos++];
        }
        token[i] = '\0';
        token_type = 'n';
        return;
    }
    
    // 处理运算符和括号
    if (strchr("+-*/()=", input[pos]) != NULL) {
        token[0] = input[pos];
        token[1] = '\0';
        token_type = input[pos];
        pos++;
        return;
    }
    
    // 其他情况视为错误
    fprintf(stderr, "Error: Unexpected character '%c'\n", input[pos]);
    exit(1);
}

// 解析表达式：expression → term { ('+' | '-') term }
ASTNode* parse_expression() {
    ASTNode* left = parse_term();
    
    while (token_type == '+' || token_type == '-') {
        char op = token_type;
        next_token();
        ASTNode* right = parse_term();
        
        ASTNode* node = (ASTNode*)malloc(sizeof(ASTNode));
        node->type = NODE_OPERATOR;
        sprintf(node->value, "%c", op);
        node->left = left;
        node->right = right;
        left = node;
    }
    
    return left;
}

// 解析项：term → factor { ('*' | '/') factor }
ASTNode* parse_term() {
    ASTNode* left = parse_factor();
    
    while (token_type == '*' || token_type == '/') {
        char op = token_type;
        next_token();
        ASTNode* right = parse_factor();
        
        ASTNode* node = (ASTNode*)malloc(sizeof(ASTNode));
        node->type = NODE_OPERATOR;
        sprintf(node->value, "%c", op);
        node->left = left;
        node->right = right;
        left = node;
    }
    
    return left;
}

// 解析因子：factor → identifier | number | '(' expression ')'
ASTNode* parse_factor() {
    ASTNode* node = NULL;
    
    if (token_type == 'i') {  // 标识符
        node = (ASTNode*)malloc(sizeof(ASTNode));
        node->type = NODE_IDENTIFIER;
        strcpy(node->value, token);
        node->left = node->right = NULL;
        next_token();
    } 
    else if (token_type == 'n') {  // 数字
        node = (ASTNode*)malloc(sizeof(ASTNode));
        node->type = NODE_NUMBER;
        strcpy(node->value, token);
        node->left = node->right = NULL;
        next_token();
    }
    else if (token_type == '(') {  // 括号表达式
        next_token();
        node = parse_expression();
        if (token_type != ')') {
            fprintf(stderr, "Error: Expected ')'\n");
            exit(1);
        }
        next_token();
    }
    else {
        fprintf(stderr, "Error: Unexpected token '%s'\n", token);
        exit(1);
    }
    
    return node;
}

// 解析赋值语句：assignment → identifier '=' expression
ASTNode* parse_assignment() {
    // 第一个token必须是标识符
    if (token_type != 'i') {
        fprintf(stderr, "Error: Expected identifier at start of assignment\n");
        exit(1);
    }
    
    char identifier[32];
    strcpy(identifier, token);
    next_token();
    
    // 下一个token必须是'='
    if (token_type != '=') {
        fprintf(stderr, "Error: Expected '=' after identifier\n");
        exit(1);
    }
    next_token();
    
    // 解析右侧表达式
    ASTNode* expr = parse_expression();
    
    // 创建赋值节点
    ASTNode* node = (ASTNode*)malloc(sizeof(ASTNode));
    node->type = NODE_ASSIGNMENT;
    strcpy(node->value, identifier);
    node->left = expr;   // 左侧存储目标变量，右侧存储表达式
    node->right = NULL;
    
    return node;
}

// 生成新的临时变量
char* new_temp() {
    static char temp[32];
    sprintf(temp, "t%d", temp_count++);
    return temp;
}

// 生成四元式
void gen_quad(const char* op, const char* arg1, const char* arg2, const char* result) {
    Quadruple q;
    strcpy(q.op, op);
    if (arg1) strcpy(q.arg1, arg1);
    else q.arg1[0] = '\0';
    if (arg2) strcpy(q.arg2, arg2);
    else q.arg2[0] = '\0';
    strcpy(q.result, result);
    quads[quad_count++] = q;
}

// 递归生成四元式代码
char* generate_code(ASTNode* node) {
    if (node == NULL) return NULL;
    
    switch (node->type) {
        case NODE_IDENTIFIER:
        case NODE_NUMBER:
            return node->value;
        
        case NODE_OPERATOR: {
            char* left_temp = generate_code(node->left);
            char* right_temp = generate_code(node->right);
            char* temp = new_temp();
            gen_quad(node->value, left_temp, right_temp, temp);
            return temp;
        }
        
        case NODE_ASSIGNMENT: {
            char* expr_temp = generate_code(node->left);
            gen_quad("=", expr_temp, NULL, node->value);
            return node->value;
        }
    }
    
    return NULL;
}

// 打印四元式表
void print_quads() {
    printf("\n%-6s %-8s %-10s %-10s %-10s\n", "Index", "Op", "Arg1", "Arg2", "Result");
    printf("----------------------------------------------------\n");
    for (int i = 0; i < quad_count; i++) {
        printf("[%-3d]  %-8s %-10s %-10s %-10s\n", 
               i, quads[i].op, 
               quads[i].arg1, quads[i].arg2, quads[i].result);
    }
}

// 打印抽象语法树（AST）
void print_ast(ASTNode* node, int depth) {
    if (node == NULL) return;
    
    // 打印缩进
    for (int i = 0; i < depth; i++) printf("  ");
    
    // 根据节点类型打印信息
    switch (node->type) {
        case NODE_IDENTIFIER:
            printf("Identifier: %s\n", node->value);
            break;
        case NODE_NUMBER:
            printf("Number: %s\n", node->value);
            break;
        case NODE_OPERATOR:
            printf("Operator: %s\n", node->value);
            print_ast(node->left, depth + 1);
            print_ast(node->right, depth + 1);
            break;
        case NODE_ASSIGNMENT:
            printf("Assignment to: %s\n", node->value);
            print_ast(node->left, depth + 1);
            break;
    }
}

// 释放AST内存
void free_ast(ASTNode* node) {
    if (node == NULL) return;
    free_ast(node->left);
    free_ast(node->right);
    free(node);
}

void get_quads(char *st){
    strncpy(input, st, sizeof(input)-1);
    // 移除换行符
    input[strcspn(input, "\n")] = '\0';
    
    // 初始化解析器
    pos = 0;
    next_token();
    
    // 解析表达式
    ASTNode* ast = parse_assignment();
    
    // 检查是否解析完成
    if (token_type != '\0') {
        fprintf(stderr, "Error: Unexpected token '%s' at end of input\n", token);
        free_ast(ast);
        return;
    }
    
    // 打印AST
    printf("\n抽象语法树 (AST):\n");
    print_ast(ast, 0);
    
    // 生成中间代码
    generate_code(ast);
    
    // 打印四元式
    printf("\n生成的三地址码（四元式）:\n");
    print_quads();
    
    // 释放内存
    free_ast(ast);
}

ICG *igc(){
    ICG *p = malloc(sizeof(ICG));
    p->get_quads=get_quads;
}